import { Request, Response } from 'express';
import { User, IUser } from '../models/User';
import { LessonPlan } from '../models/LessonPlan';
import { File } from '../models/File';
import { AuthRequest } from '../middleware/auth';
import { logger } from '../utils/logger';
import { createError } from '../middleware/errorHandler';
import { checkPasswordStrength, isPasswordReused } from '../utils/password';
import mongoose from 'mongoose';
import fs from 'fs';
import path from 'path';
import { ActivityService } from '../services/ActivityService';

export class UserController {
  // 获取用户个人资料
  public getProfile = async (req: AuthRequest, res: Response): Promise<void> => {
    try {
      if (!req.user) {
        logger.warn('获取用户资料失败: 用户未认证');
        res.status(401).json({
          success: false,
          message: '用户认证失败',
          code: 'UNAUTHENTICATED'
        });
        return;
      }

      logger.info('获取用户资料请求', { userId: req.user.id });

      const user = await User.findById(req.user.id)
        .select('-password -passwordHistory -resetPasswordToken -resetPasswordExpires');
      
      if (!user) {
        logger.warn('获取用户资料失败: 用户不存在', { userId: req.user.id });
        res.status(404).json({
          success: false,
          message: '用户不存在',
          code: 'USER_NOT_FOUND'
        });
        return;
      }

      logger.info('获取用户资料成功', { userId: req.user.id });

      res.json({
        success: true,
        data: {
          id: user._id,
          email: user.email,
          name: user.name,
          role: user.role,
          avatar: user.avatar,
          bio: user.bio,
          lastPasswordChange: user.lastPasswordChange,
          createdAt: user.createdAt,
          updatedAt: user.updatedAt
        }
      });
    } catch (error: any) {
      logger.error('获取用户资料失败', { 
        userId: req.user?.id,
        error: error.message,
        stack: error.stack
      });
      res.status(500).json({
        success: false,
        message: '获取用户资料失败，请稍后重试',
        code: 'INTERNAL_ERROR'
      });
    }
  };

  // 更新用户个人资料
  public updateProfile = async (req: AuthRequest, res: Response): Promise<void> => {
    try {
      if (!req.user) {
        logger.warn('更新用户资料失败: 用户未认证');
        res.status(401).json({
          success: false,
          message: '用户认证失败',
          code: 'UNAUTHENTICATED'
        });
        return;
      }

      const { name, avatar, bio } = req.body;

      logger.info('更新用户资料请求', { 
        userId: req.user.id, 
        fields: { name: !!name, avatar: !!avatar, bio: !!bio } 
      });

      const updateData: Partial<IUser> = {};

      // 更新姓名
      if (name !== undefined) {
        if (!name || name.trim() === '') {
          res.status(400).json({
            success: false,
            message: '姓名不能为空',
            code: 'INVALID_NAME'
          });
          return;
        }
        updateData.name = name.trim();
      }

      // 更新头像
      if (avatar !== undefined) {
        updateData.avatar = avatar || '';
      }

      // 更新个人简介
      if (bio !== undefined) {
        if (bio && bio.length > 500) {
          res.status(400).json({
            success: false,
            message: '个人简介不能超过500个字符',
            code: 'BIO_TOO_LONG'
          });
          return;
        }
        updateData.bio = bio || '';
      }

      // 如果没有任何更新字段
      if (Object.keys(updateData).length === 0) {
        res.status(400).json({
          success: false,
          message: '没有提供需要更新的字段',
          code: 'NO_UPDATE_FIELDS'
        });
        return;
      }

      const user = await User.findByIdAndUpdate(
        req.user.id,
        updateData,
        { new: true, runValidators: true }
      ).select('-password -passwordHistory -resetPasswordToken -resetPasswordExpires');

      if (!user) {
        logger.warn('更新用户资料失败: 用户不存在', { userId: req.user.id });
        res.status(404).json({
          success: false,
          message: '用户不存在',
          code: 'USER_NOT_FOUND'
        });
        return;
      }

      logger.info('更新用户资料成功', { 
        userId: req.user.id,
        updatedFields: Object.keys(updateData)
      });

      res.json({
        success: true,
        message: '个人资料更新成功',
        data: {
          id: user._id,
          email: user.email,
          name: user.name,
          role: user.role,
          avatar: user.avatar,
          bio: user.bio,
          lastPasswordChange: user.lastPasswordChange,
          createdAt: user.createdAt,
          updatedAt: user.updatedAt
        }
      });
    } catch (error: any) {
      logger.error('更新用户资料失败', { 
        userId: req.user?.id,
        error: error.message,
        stack: error.stack
      });

      if (error.name === 'ValidationError') {
        const validationErrors = Object.values(error.errors).map((err: any) => err.message);
        res.status(400).json({
          success: false,
          message: '数据验证失败',
          code: 'VALIDATION_ERROR',
          errors: validationErrors
        });
      } else {
        res.status(500).json({
          success: false,
          message: '更新用户资料失败，请稍后重试',
          code: 'INTERNAL_ERROR'
        });
      }
    }
  };

  // 修改密码
  public changePassword = async (req: AuthRequest, res: Response): Promise<void> => {
    try {
      if (!req.user) {
        logger.warn('修改密码失败: 用户未认证');
        res.status(401).json({
          success: false,
          message: '用户认证失败',
          code: 'UNAUTHENTICATED'
        });
        return;
      }

      const { currentPassword, newPassword } = req.body;

      logger.info('修改密码请求', { userId: req.user.id });

      // 验证必需字段
      if (!currentPassword || !newPassword) {
        res.status(400).json({
          success: false,
          message: '当前密码和新密码为必填项',
          code: 'MISSING_PASSWORDS'
        });
        return;
      }

      // 获取用户信息
      const user = await User.findById(req.user.id);
      if (!user) {
        logger.warn('修改密码失败: 用户不存在', { userId: req.user.id });
        res.status(404).json({
          success: false,
          message: '用户不存在',
          code: 'USER_NOT_FOUND'
        });
        return;
      }

      // 验证当前密码
      const isCurrentPasswordValid = await user.comparePassword(currentPassword);
      if (!isCurrentPasswordValid) {
        logger.warn('修改密码失败: 当前密码错误', { userId: req.user.id });
        res.status(400).json({
          success: false,
          message: '当前密码不正确',
          code: 'INVALID_CURRENT_PASSWORD'
        });
        return;
      }

      // 检查新密码强度
      const strengthCheck = checkPasswordStrength(newPassword);
      if (!strengthCheck.isValid) {
        logger.warn('修改密码失败: 新密码强度不足', { userId: req.user.id });
        res.status(400).json({
          success: false,
          message: '新密码强度不足',
          code: 'WEAK_PASSWORD',
          errors: strengthCheck.feedback
        });
        return;
      }

      // 检查是否重复使用旧密码
      if (user.passwordHistory && user.passwordHistory.length > 0) {
        const isReused = await isPasswordReused((user._id as any).toString(), newPassword, user.passwordHistory);
        if (isReused) {
          logger.warn('修改密码失败: 密码重复使用', { userId: req.user.id });
          res.status(400).json({
            success: false,
            message: '不能使用最近使用过的密码',
            code: 'PASSWORD_REUSED'
          });
          return;
        }
      }

      // 检查新密码是否与当前密码相同
      if (currentPassword === newPassword) {
        res.status(400).json({
          success: false,
          message: '新密码不能与当前密码相同',
          code: 'SAME_PASSWORD'
        });
        return;
      }

      // 更新密码
      user.password = newPassword;
      user.lastPasswordChange = new Date();
      await user.save();

      logger.info('修改密码成功', { userId: req.user.id });

      res.json({
        success: true,
        message: '密码修改成功'
      });
    } catch (error: any) {
      logger.error('修改密码失败', { 
        userId: req.user?.id,
        error: error.message,
        stack: error.stack
      });

      res.status(500).json({
        success: false,
        message: '修改密码失败，请稍后重试',
        code: 'INTERNAL_ERROR'
      });
    }
  };

  // 上传用户头像
  public uploadAvatar = async (req: AuthRequest, res: Response): Promise<void> => {
    try {
      if (!req.user) {
        logger.warn('上传头像失败: 用户未认证');
        res.status(401).json({
          success: false,
          message: '用户认证失败',
          code: 'UNAUTHENTICATED'
        });
        return;
      }

      if (!req.file) {
        logger.warn('上传头像失败: 未提供文件', { userId: req.user.id });
        res.status(400).json({
          success: false,
          message: '请选择要上传的头像文件',
          code: 'NO_FILE_PROVIDED'
        });
        return;
      }

      logger.info('开始上传头像', { 
        userId: req.user.id, 
        fileName: req.file.originalname,
        fileSize: req.file.size,
        mimeType: req.file.mimetype
      });

      // 获取用户当前信息
      const user = await User.findById(req.user.id);
      if (!user) {
        // 删除已上传的文件
        if (fs.existsSync(req.file.path)) {
          fs.unlinkSync(req.file.path);
        }
        
        logger.warn('上传头像失败: 用户不存在', { userId: req.user.id });
        res.status(404).json({
          success: false,
          message: '用户不存在',
          code: 'USER_NOT_FOUND'
        });
        return;
      }

      // 删除旧头像文件
      if (user.avatar && user.avatar.startsWith('/uploads/avatars/')) {
        const oldAvatarPath = path.join(process.cwd(), user.avatar);
        if (fs.existsSync(oldAvatarPath)) {
          try {
            fs.unlinkSync(oldAvatarPath);
            logger.info('删除旧头像文件成功', { userId: req.user.id, oldPath: oldAvatarPath });
          } catch (error) {
            logger.warn('删除旧头像文件失败', { userId: req.user.id, oldPath: oldAvatarPath, error });
          }
        }
      }

      // 构建新头像URL
      const avatarUrl = `/uploads/avatars/${req.file.filename}`;

      // 更新用户头像
      const updatedUser = await User.findByIdAndUpdate(
        req.user.id,
        { avatar: avatarUrl },
        { new: true, runValidators: true }
      ).select('-password -passwordHistory -resetPasswordToken -resetPasswordExpires');

      if (!updatedUser) {
        // 删除已上传的文件
        if (fs.existsSync(req.file.path)) {
          fs.unlinkSync(req.file.path);
        }
        
        logger.error('更新用户头像失败: 用户不存在', { userId: req.user.id });
        res.status(404).json({
          success: false,
          message: '用户不存在',
          code: 'USER_NOT_FOUND'
        });
        return;
      }

      logger.info('头像上传成功', { 
        userId: req.user.id,
        avatarUrl,
        fileSize: req.file.size
      });

      res.json({
        success: true,
        message: '头像上传成功',
        data: {
          avatar: avatarUrl,
          user: {
            id: updatedUser._id,
            email: updatedUser.email,
            name: updatedUser.name,
            role: updatedUser.role,
            avatar: updatedUser.avatar,
            bio: updatedUser.bio,
            lastPasswordChange: updatedUser.lastPasswordChange,
            createdAt: updatedUser.createdAt,
            updatedAt: updatedUser.updatedAt
          }
        }
      });
    } catch (error: any) {
      // 清理已上传的文件
      if (req.file && fs.existsSync(req.file.path)) {
        try {
          fs.unlinkSync(req.file.path);
        } catch (cleanupError) {
          logger.error('清理上传文件失败', { 
            filePath: req.file.path, 
            error: cleanupError 
          });
        }
      }

      logger.error('上传头像失败', { 
        userId: req.user?.id,
        error: error.message,
        stack: error.stack
      });

      res.status(500).json({
        success: false,
        message: '上传头像失败，请稍后重试',
        code: 'INTERNAL_ERROR'
      });
    }
  };

  // 删除用户头像
  public deleteAvatar = async (req: AuthRequest, res: Response): Promise<void> => {
    try {
      if (!req.user) {
        logger.warn('删除头像失败: 用户未认证');
        res.status(401).json({
          success: false,
          message: '用户认证失败',
          code: 'UNAUTHENTICATED'
        });
        return;
      }

      logger.info('删除头像请求', { userId: req.user.id });

      // 获取用户当前信息
      const user = await User.findById(req.user.id);
      if (!user) {
        logger.warn('删除头像失败: 用户不存在', { userId: req.user.id });
        res.status(404).json({
          success: false,
          message: '用户不存在',
          code: 'USER_NOT_FOUND'
        });
        return;
      }

      // 删除头像文件
      if (user.avatar && user.avatar.startsWith('/uploads/avatars/')) {
        const avatarPath = path.join(process.cwd(), user.avatar);
        if (fs.existsSync(avatarPath)) {
          try {
            fs.unlinkSync(avatarPath);
            logger.info('删除头像文件成功', { userId: req.user.id, avatarPath });
          } catch (error) {
            logger.warn('删除头像文件失败', { userId: req.user.id, avatarPath, error });
          }
        }
      }

      // 更新用户头像为空
      const updatedUser = await User.findByIdAndUpdate(
        req.user.id,
        { avatar: '' },
        { new: true, runValidators: true }
      ).select('-password -passwordHistory -resetPasswordToken -resetPasswordExpires');

      if (!updatedUser) {
        logger.error('更新用户头像失败: 用户不存在', { userId: req.user.id });
        res.status(404).json({
          success: false,
          message: '用户不存在',
          code: 'USER_NOT_FOUND'
        });
        return;
      }

      logger.info('删除头像成功', { userId: req.user.id });

      res.json({
        success: true,
        message: '头像删除成功',
        data: {
          user: {
            id: updatedUser._id,
            email: updatedUser.email,
            name: updatedUser.name,
            role: updatedUser.role,
            avatar: updatedUser.avatar,
            bio: updatedUser.bio,
            lastPasswordChange: updatedUser.lastPasswordChange,
            createdAt: updatedUser.createdAt,
            updatedAt: updatedUser.updatedAt
          }
        }
      });
    } catch (error: any) {
      logger.error('删除头像失败', { 
        userId: req.user?.id,
        error: error.message,
        stack: error.stack
      });

      res.status(500).json({
        success: false,
        message: '删除头像失败，请稍后重试',
        code: 'INTERNAL_ERROR'
      });
    }
  };

  // 获取用户统计数据
  public getStats = async (req: AuthRequest, res: Response): Promise<void> => {
    try {
      if (!req.user) {
        res.status(401).json({
          success: false,
          message: '用户认证失败'
        });
        return;
      }

      const userId = new mongoose.Types.ObjectId(req.user.id);

      // 并行获取统计数据
      const [
        totalLessonPlans,
        publishedLessonPlans,
        draftLessonPlans,
        totalViews,
        totalLikes,
        uploadedFiles,
        totalFileSize,
        recentLessonPlans
      ] = await Promise.all([
        // 总教案数
        LessonPlan.countDocuments({ author: userId }),
        
        // 已发布教案数
        LessonPlan.countDocuments({ author: userId, status: 'published' }),
        
        // 草稿教案数
        LessonPlan.countDocuments({ author: userId, status: 'draft' }),
        
        // 总浏览数
        LessonPlan.aggregate([
          { $match: { author: userId } },
          { $group: { _id: null, totalViews: { $sum: '$views' } } }
        ]).then(result => result[0]?.totalViews || 0),
        
        // 总点赞数
        LessonPlan.aggregate([
          { $match: { author: userId } },
          { $group: { _id: null, totalLikes: { $sum: '$likes' } } }
        ]).then(result => result[0]?.totalLikes || 0),
        
        // 上传文件数
        File.countDocuments({ uploader: userId }),
        
        // 总文件大小
        File.aggregate([
          { $match: { uploader: userId } },
          { $group: { _id: null, totalSize: { $sum: '$size' } } }
        ]).then(result => result[0]?.totalSize || 0),
        
        // 最近的教案
        LessonPlan.find({ author: userId })
          .sort({ createdAt: -1 })
          .limit(5)
          .select('title status createdAt views likes')
      ]);

      // 按月份统计教案创建数量
      const monthlyStats = await LessonPlan.aggregate([
        { $match: { author: userId } },
        {
          $group: {
            _id: {
              year: { $year: '$createdAt' },
              month: { $month: '$createdAt' }
            },
            count: { $sum: 1 }
          }
        },
        { $sort: { '_id.year': -1, '_id.month': -1 } },
        { $limit: 12 }
      ]);

      // 按学科统计教案数量
      const subjectStats = await LessonPlan.aggregate([
        { $match: { author: userId } },
        {
          $group: {
            _id: '$subject',
            count: { $sum: 1 }
          }
        },
        { $sort: { count: -1 } }
      ]);

      res.json({
        success: true,
        data: {
          summary: {
            totalLessonPlans,
            publishedLessonPlans,
            draftLessonPlans,
            archivedLessonPlans: totalLessonPlans - publishedLessonPlans - draftLessonPlans,
            totalViews,
            totalLikes,
            uploadedFiles,
            totalFileSize: Math.round(totalFileSize / 1024 / 1024 * 100) / 100 // MB
          },
          charts: {
            monthlyStats: monthlyStats.map(stat => ({
              period: `${stat._id.year}-${stat._id.month.toString().padStart(2, '0')}`,
              count: stat.count
            })),
            subjectStats: subjectStats.map(stat => ({
              subject: stat._id,
              count: stat.count
            }))
          },
          recentActivity: {
            recentLessonPlans: recentLessonPlans.map(plan => ({
              id: plan._id,
              title: plan.title,
              status: plan.status,
              createdAt: plan.createdAt,
              views: plan.views,
              likes: plan.likes
            }))
          }
        }
      });
    } catch (error) {
      console.error('获取用户统计数据错误:', error);
      res.status(500).json({
        success: false,
        message: '服务器内部错误'
      });
    }
  };

  // 获取用户活动记录
  public getActivities = async (req: AuthRequest, res: Response): Promise<void> => {
    try {
      if (!req.user) {
        res.status(401).json({
          success: false,
          message: '用户认证失败',
          code: 'UNAUTHENTICATED'
        });
        return;
      }

      const page = parseInt(req.query.page as string) || 1;
      const limit = parseInt(req.query.limit as string) || 10;
      const skip = (page - 1) * limit;

      logger.info('获取用户活动记录请求', { 
        userId: req.user.id, 
        page, 
        limit 
      });

      // 获取活动记录
      const activities = await ActivityService.getUserActivities(
        req.user.id,
        limit,
        skip
      );

      // 获取总数
      const { Activity } = await import('../models/Activity');
      const total = await Activity.countDocuments({ user: req.user.id });

      logger.info('获取用户活动记录成功', { 
        userId: req.user.id,
        count: activities.length,
        total
      });

      res.json({
        success: true,
        data: {
          activities: activities.map(activity => ({
            id: activity._id,
            type: activity.type,
            target: activity.target,
            targetId: activity.targetId,
            targetTitle: activity.targetTitle,
            content: activity.content,
            metadata: activity.metadata,
            createdAt: activity.createdAt
          })),
          pagination: {
            page,
            limit,
            total,
            pages: Math.ceil(total / limit)
          }
        }
      });
    } catch (error: any) {
      logger.error('获取用户活动记录失败', { 
        userId: req.user?.id,
        error: error.message,
        stack: error.stack
      });

      res.status(500).json({
        success: false,
        message: '获取活动记录失败，请稍后重试',
        code: 'INTERNAL_ERROR'
      });
    }
  };
}